﻿namespace TestTool.HttpTransport.Internals.Http
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Xml;
    using TestTool.HttpTransport.Interfaces;
    using TestTool.HttpTransport.Interfaces.Exceptions;

    internal class HttpHelper
    {
        public const string APPLICATIONSOAPXML = "application/soap+xml";
        private const string CHARSET = "charset";
        public const string CONNECTION = "Connection";
        public const string CONTENTLENGTH = "Content-Length";
        public const string CONTENTTYPE = "Content-Type";
        private const string HOSTLINEPATTERN = "Host: {0}\r\n";
        private const string STATUSLINEPATTERN = "POST {0} HTTP/1.1\r\n";
        private const string UTF8 = "utf-8";

        public static bool ContinueReading(MemoryStream responseStream, out HttpPacket header)
        {
            MemoryStream stream = new MemoryStream(responseStream.GetBuffer());
            StreamReader reader = new StreamReader(stream);
            header = new HttpPacket();
            int result = 0;
            int num2 = 0;
            bool flag = false;
            bool flag2 = true;
            bool flag3 = false;
            while (!reader.EndOfStream)
            {
                string str = reader.ReadLine();
                num2 += 2 + str.Length;
                if ((str == null) || (!string.IsNullOrEmpty(str) && string.IsNullOrEmpty(str.Trim(new char[1]))))
                {
                    break;
                }
                if (flag2)
                {
                    string[] strArray = str.Split(new char[] { ' ' });
                    if (strArray.Length <= 2)
                    {
                        throw new HttpProtocolException(string.Format("The first line of a Response message is incorrect: {0}", str));
                    }
                    string s = strArray[1].Trim();
                    header.HttpVersion = strArray[0];
                    header.StatusCode = int.Parse(s);
                    int startIndex = (strArray[0].Length + strArray[1].Length) + 2;
                    header.StatusDescription = str.Substring(startIndex);
                    if (((s == "204") || (s == "304")) || s.StartsWith("1"))
                    {
                        flag3 = true;
                    }
                    flag2 = false;
                }
                else
                {
                    int index = str.IndexOf(':');
                    if (index > 0)
                    {
                        string y = str.Substring(0, index).Trim();
                        string str4 = str.Substring(index + 1).Trim();
                        bool flag4 = true;
                        if ((StringComparer.CurrentCultureIgnoreCase.Compare("WWW-Authenticate", y) == 0) && !str4.ToLower().StartsWith("digest"))
                        {
                            flag4 = false;
                        }
                        if (StringComparer.CurrentCultureIgnoreCase.Compare("Connection", y) == 0)
                        {
                            header.Connection.Add(str4);
                            flag4 = false;
                        }
                        if (StringComparer.CurrentCultureIgnoreCase.Compare("Proxy-Support", y) == 0)
                        {
                            flag4 = false;
                        }
                        if (flag4)
                        {
                            header.Headers.Add(y, str4);
                        }
                        if (StringComparer.InvariantCultureIgnoreCase.Compare(y, "Content-Length") == 0)
                        {
                            if (!int.TryParse(str4, out result))
                            {
                                throw new HttpProtocolException(string.Format("Content-Length incorrect: {0}, integer expected", str4));
                            }
                            header.ContentLength = result;
                        }
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(str))
                        {
                            throw new HttpProtocolException(string.Format("Unexpected header format: {0}", str));
                        }
                        flag = true;
                        break;
                    }
                }
            }
            header.BodyOffset = num2;
            header.NoBodySupposed = flag3;
            if (flag)
            {
                if (flag3)
                {
                    return false;
                }
                if (result <= (responseStream.Length - num2))
                {
                    return false;
                }
            }
            return true;
        }

        public static byte[] CreateHttpHeaders(long size, string path, string address, HttpPacket packet, string username, string password, DigestTestingSettings testingSettings)
        {
            StringBuilder builder = new StringBuilder();
            builder.AppendFormat("POST {0} HTTP/1.1\r\n", path);
            builder.AppendFormat("Host: {0}\r\n", address);
            builder.AppendFormat("{0}: {1}; {2}={3}\r\n", new object[] { "Content-Type", "application/soap+xml", "charset", "utf-8" });
            if (packet != null)
            {
                HttpDigest.DigestAuthenticationParameters authenticationParameters = new HttpDigest.DigestAuthenticationParameters {
                    Address = path,
                    Challenge = packet,
                    UserName = username,
                    Password = password
                };
                builder.AppendFormat("{0}\r\n", HttpDigest.CreateDigestAuthenticationHeader(authenticationParameters, testingSettings));
            }
            builder.Append("Content-Length: " + size.ToString() + "\r\n");
            builder.Append("\r\n");
            return Encoding.UTF8.GetBytes(builder.ToString());
        }

        public static string GetFormattedMessage(byte[] messageBytes, int bodyOffset)
        {
            try
            {
                int length = messageBytes.Length - bodyOffset;
                byte[] destinationArray = new byte[length];
                Array.Copy(messageBytes, bodyOffset, destinationArray, 0, length);
                string xml = Encoding.UTF8.GetString(destinationArray);
                XmlDocument document = new XmlDocument();
                document.LoadXml(xml);
                MemoryStream stream = new MemoryStream();
                stream.Write(messageBytes, 0, bodyOffset);
                MemoryStream outStream = new MemoryStream();
                document.Save(outStream);
                int index = 0;
                byte[] buffer = outStream.GetBuffer();
                while (buffer[index] != 60)
                {
                    index++;
                }
                stream.Write(buffer, index, ((int) outStream.Length) - index);
                string str2 = Encoding.UTF8.GetString(stream.GetBuffer(), 0, (int) stream.Length);
                outStream.Close();
                stream.Close();
                return str2;
            }
            catch (Exception)
            {
                return Encoding.UTF8.GetString(messageBytes);
            }
        }

        public static bool ValidateHttpHeaders(HttpPacket packet)
        {
            if (!packet.Headers.ContainsKey("Content-Type"))
            {
                throw new HttpProtocolException("Mandatory Content-Type header not found.");
            }
            string str = packet.Headers["Content-Type"].Trim();
            List<string> list = new List<string>();
            bool flag = false;
            int startIndex = 0;
            for (int i = 0; i < str.Length; i++)
            {
                char ch = str[i];
                if ((ch == ';') && !flag)
                {
                    string item = str.Substring(startIndex, i - startIndex).Trim();
                    startIndex = i + 1;
                    list.Add(item);
                }
                if (ch == '"')
                {
                    flag = !flag;
                }
            }
            if (startIndex != str.Length)
            {
                string str3 = str.Substring(startIndex, str.Length - startIndex).Trim();
                list.Add(str3);
            }
            if (list.Count == 0)
            {
                throw new HttpProtocolException("Content-Type not defined");
            }
            string str4 = list[0];
            packet.ContentType = str4;
            for (int j = 1; j < list.Count; j++)
            {
                string[] strArray = list[j].Trim().Split(new char[] { '=' });
                if ((strArray.Length > 1) && (StringComparer.InvariantCultureIgnoreCase.Compare(strArray[0], "charset") == 0))
                {
                    packet.Encoding = strArray[1].Trim();
                    if (StringComparer.InvariantCultureIgnoreCase.Compare(packet.Encoding, "utf-8") != 0)
                    {
                        throw new HttpProtocolException(string.Format("Charset mismatch. Expected: utf-8, actual: {0}", packet.Encoding));
                    }
                }
            }
            return true;
        }
    }
}

